package com.junsi.common.utils.oss;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author yikun.he
 * @version 1.0
 * @date 2019/2/11
 * @desc
 * @see
 * @since 1.0
 */
public class OssClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(OssClient.class);
    private static final Integer TIME_SIXTY_TOOL = 60;
    private static final Integer ONE_THOUSAND_TOOL = 1000;
    private static final Integer HOURS_TO_DAY = 24;
    private static final Integer DAY_TO_YEAR = 365;
    private static final Integer TEN_VALUE = 10;
    @Autowired
    private OssProperties ossProperties;
    private static OssProperties ossPropertiesBean= new OssProperties();

    private static OSSClient client = null;

    public OssClient() {
    }

    @PostConstruct
    public synchronized void init() {
        BeanUtils.copyProperties(ossProperties, ossPropertiesBean);
        LOGGER.info("获取OSS配置信息...");
        LOGGER.info("OssClient.Producer 初始化...");
        String endpoint = ossPropertiesBean.getEndpoint();
        final String accessKeyId = ossPropertiesBean.getAccessKeyId();
        final String accessKeySecret = ossPropertiesBean.getAccessKeySecret();
        String bucketName = ossPropertiesBean.getBucketName();
        boolean flag = false;
        if (ossPropertiesBean.getAgreement() != null) {
            LOGGER.info("aliyun.oss.agreement {}", ossPropertiesBean.getAgreement());
        } else {
            LOGGER.info("aliyun.oss.agreement http");
        }

        if (endpoint != null && !endpoint.equals("")) {
            LOGGER.info("aliyun.oss.endpoint endpoint [{}]", endpoint);
        } else {
            LOGGER.error("aliyun.oss.endpoint 没有配置 !");
            flag = true;
        }

        if (accessKeyId != null && !accessKeyId.equals("")) {
            LOGGER.info("aliyun.oss.accessKeyId [{}]", accessKeyId);
        } else {
            LOGGER.error("aliyun.oss.accessKeyId 没有配置 !");
            flag = true;
        }

        if (accessKeySecret != null && !accessKeySecret.equals("")) {
            LOGGER.info("aliyun.oss.accessKeySecret [{}]", accessKeySecret);
        } else {
            LOGGER.error("aliyun.oss.accessKeySecret 没有配置 !");
            flag = true;
        }

        if (bucketName != null && !bucketName.equals("")) {
            LOGGER.info("aliyun.oss.bucketName [{}]", bucketName);
        } else {
            LOGGER.error("aliyun.oss.bucketName 没有配置 !");
            flag = true;
        }

        if (flag) {
            LOGGER.error("信息配置不完整，客户端未初始化...");
        } else {
            Credentials credentials = new Credentials() {
                @Override
                public String getAccessKeyId() {
                    return accessKeyId;
                }

                @Override
                public String getSecretAccessKey() {
                    return accessKeySecret;
                }

                @Override
                public String getSecurityToken() {
                    return null;
                }

                @Override
                public boolean useSecurityToken() {
                    return false;
                }
            };
            ClientConfiguration clientConfiguration = new ClientConfiguration();
            clientConfiguration.setSLDEnabled(false);
            clientConfiguration.setProxyWorkstation("");
            CredentialsProvider credentialsProvider = new CredentialsProvider() {
                private Credentials creds = null;

                @Override
                public void setCredentials(Credentials creds) {
                    this.creds = creds;
                }

                @Override
                public Credentials getCredentials() {
                    return this.creds;
                }
            };
            credentialsProvider.setCredentials(credentials);
            client = new OSSClient(endpoint, credentialsProvider, clientConfiguration);
            LOGGER.info("ossClient 创建成功......");
        }

    }

    @PreDestroy
    public void destroy() {
        LOGGER.info("oss销毁...");
        client.shutdown();
    }


    /** 上传文件*/
    public static String upload(InputStream inputStream, String suffix) {
        try {
            String directory = ossPropertiesBean.getDirectory().endsWith("/") ? ossPropertiesBean.getDirectory() : ossPropertiesBean.getDirectory() + "/";
            String key = directory + UUID.randomUUID().toString() + "." + suffix;
            client.putObject(new PutObjectRequest(ossPropertiesBean.getBucketName(), key, inputStream));
            String url = getUrl(key);
            return url;
        } catch (Exception var6) {
            var6.printStackTrace();
            return "";
        }
    }

    public static Map<String,String> getParam() {
        Map<String, String> resultMap = new HashMap();
        String endpoint = ossPropertiesBean.getEndpoint();
        String accessKeyId = ossPropertiesBean.getAccessKeyId();
        String bucketName = ossPropertiesBean.getBucketName();
        StringBuffer host = new StringBuffer();
        if (ossPropertiesBean.getAgreement() != null && ossPropertiesBean.getAgreement().equals("https")) {
            host.append("https://");
        } else {
            host.append("http://");
        }

        host.append(bucketName).append(".").append(endpoint);
        String directory = ossPropertiesBean.getDirectory();
        long expireTime = 300L;
        long expireEndTime = System.currentTimeMillis() + expireTime * 1000L;
        java.sql.Date expiration = new java.sql.Date(expireEndTime);
        PolicyConditions policyCond = new PolicyConditions();
        policyCond.addConditionItem("content-length-range", 0L, 1048576000L);
        policyCond.addConditionItem(MatchMode.StartWith, "key", directory);
        String postPolicy = client.generatePostPolicy(expiration, policyCond);

        try {
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = client.calculatePostSignature(postPolicy);
            resultMap.put("policy", encodedPolicy);
            resultMap.put("signature", postSignature);
        } catch (UnsupportedEncodingException var16) {
            var16.printStackTrace();
        }

        resultMap.put("accessKeyId", accessKeyId);
        resultMap.put("directory", directory);
        resultMap.put("host", host.toString());
        resultMap.put("expire", String.valueOf(expireEndTime / 1000L));
        return resultMap;
    }

    public static String getUrl(String key) {
        Date expiration = new Date((new Date()).getTime() + (long)(TIME_SIXTY_TOOL * TIME_SIXTY_TOOL * ONE_THOUSAND_TOOL * HOURS_TO_DAY * DAY_TO_YEAR * TEN_VALUE * TEN_VALUE));
        URL url = client.generatePresignedUrl(ossPropertiesBean.getBucketName(), key, expiration);
        if (url != null) {
            String urlStr = url.toString();
            String returnUrl = urlStr.substring(0, urlStr.indexOf("?"));
            return returnUrl;
        } else {
            return null;
        }
    }

	//使用签名URL进行临时授权
	public static String getTmpUrl(String key) {
		// 设置URL过期时间为1小时。
		Date expiration = new Date((new Date()).getTime() + (long)(TIME_SIXTY_TOOL * TIME_SIXTY_TOOL * ONE_THOUSAND_TOOL));
		URL url = client.generatePresignedUrl(ossPropertiesBean.getBucketName(), key, expiration);
		return url.toString();
	}
}
